# -*- coding: utf-8 -*-
import codecs
import re
import parser

juuri = {
    u"Kansainvälinen" : -2,
    u"Suomi" : -1,
    u"Englanti" : 0,
    u"Ruotsi" : 0,
    u"Espanja" : 0,
    u"Ranska" : 0,
    u"Venäjä" : 0,
    u"Viro" : 0,
    u"Tšekki" : 0,
    u"Turkki" : 0,
    u"Latvia" : 0,
    u"Liettua" : 0,
    u"Võro" : 0,
    u"Portugali" : 0,
    u"Italia" : 0,
    u"Tanska" : 0,
    u"Islanti" : 0,
    u"Norja" : 0,
#    u"Lähteet" : +1,
    u"Viitteet" : +2,

    }

kieli = {
    u"Aakkonen", 
    u"Adjektiivi", 
    u"Adverbi", 
    u"Erisnimi", 
    u"Fraasi", 
    u"Interjektio", 
    u"Konjunktio", 
    u"Lyhenne", 
    u"Numeraali", 
    u"Postpositio", 
    u"Prefiksi", 
    u"Pronomini", 
    u"Substantiivi", 
    u"Suffiksi", 
    u"Symboli", 
    u"Supistuma", 
    u"Verbi",
}

sanalk = {
    u"Ääntäminen" : 0, 
    u"Taivutus" : 1, 
    u"Huomautukset" : 2, 
    u"Etymologia" : 3, 
    u"Käännökset" : 4, 
    u"Lainaukset" : 5, 
    u"Liittyvät sanat" : 6, 
    u"Idiomit" : 7, 
    u"Aiheesta muualla" : 8, 
#    u"Lähteet" : 9, 
}

liittyvat = {
    u"Rinnakkaiset kirjoitusasut" : 0, 
    u"Rinnakkaismuodot" : 10, 
    u"Synonyymit" : 20, 
    u"Vastakohdat" : 30, 
    u"Johdokset" : 40, 
    u"Yhdyssanat" : 50, 
    u"Sanaliitot" : 55, 
    u"Yhdyssanat ja sanaliitot" : 60, 
    u"Tästä johtuvat tytärkielten sanat" : 70, 
    u"Lainat muissa kielissä" : 80, 
    u"Yläkäsitteet" : 90, 
    u"Vieruskäsitteet" : 100, 
    u"Alakäsitteet" : 110, 
    u"Osakäsitteet" : 120, 
    u"Kokonaiskäsitteet" : 130, 
}


class KorjausParseri(object):

    def __init__(self, data):
        self.data = data
        self.ei_voi_korjata = False
        self.teot = []
        self.f = open("otsikkokorjaus.log", "a")
        self.i_rak = self.parsi_rakenne(data)
        self.korjattu = self.parsi(data)
        if not self.ei_voi_korjata:
            try:
                self.w = parser.WiktSivu(self.korjattu)
                self.korjattu = self.w.teksti()
                self.teot = self.w.muutokset
                if re.search(u"\[\[Luokka:Otsikko korjattava\]\]", self.korjattu):
                    self.korjattu = re.sub(u"\[\[Luokka:Otsikko korjattava\]\]\n", "", self.korjattu)
                    self.teot.append("poistettu lk:Otsikko korjattava")
            except parser.DuplikaattiException as de:
#                self.korjattu = u"[[Luokka:Otsikko korjattava]]\n" + self.korjattu
#                self.teot.append(u"+luokka: Otsikko korjattava ({})".format(de))
                pass

        self.korjattu = re.sub("\n\n\n+", "\n\n", self.korjattu)
        self.o_rak = self.parsi_rakenne(self.korjattu)
        if self.o_rak != self.i_rak:
            self.teot.append(u"osiot järjestetty")
        self.f.close()

    def teksti(self):
        return self.korjattu

    def hae_taso(self, otsikko, origtaso):
        if otsikko in juuri:
            return 2
        elif otsikko in kieli:
            return 3
        elif otsikko in sanalk: 
            return 4
        elif otsikko in liittyvat:
            return 5
        return origtaso

    def tee_otsikko(self, teksti, origtaso):
        taso = self.hae_taso(teksti, origtaso)
        self.f.write((u"tuntematon otsikko: " + teksti).encode("utf-8"))

        return u"\n" + (taso * "=") + teksti + (taso * "=")

    def parsi(self, data):
        iteksti = u"\n" + data
        oteksti = []
        re_m = re.compile(u"\n(==+ *)(.*?)( *==+ *)")
        re_r = re.compile(u"^\n(==+ *)(.*?)( *==+ *)")
        tehty = 0
        m = True
        a = 0
        stack = [(1, u"[juuri]")]
        while m:
            m = re.search(re_m, iteksti[a:])

            if m:

#                print u"OSA[[[\n{}\n]]".format(iteksti[a:a+m.start()])
                oteksti.append(iteksti[a:a+m.start()])
#                print(u"otsikko: {}".format(m.group(2)))
                otsikko = m.group(2)
                taso = len(m.group(1).strip())
                u_taso = self.hae_taso(otsikko, taso)
                while stack[-1][0] >= u_taso:
                    stack.pop()
                

                if (otsikko in liittyvat) and stack[-1][1] != u"Liittyvät sanat":
                    tehty += 1
                    otsikko2 = self.tee_otsikko(u"Liittyvät sanat", taso);
#                    print u"otsikko: " + otsikko2
                    oteksti.append(otsikko2)
                elif u_taso > stack[-1][0] + 1:                
#                    self.teot.append(u"+luokka: Otsikko korjattava (tasoero vanhempaan > 1: {})".format(otsikko))
                    self.ei_voi_korjata = True
#                    return u"[[Luokka:Otsikko korjattava]]\n" + data
                    return data
                    
                if otsikko == u"Lyhenne" and (stack[-1][1] in sanalk or stack[-1][1] == u"Liittyvät sanat"):
                    # Sanaluokan alla tai Liittyvät sanat -osiossa on joskus myös lyhenneotsikko
                    pass
                elif u_taso != 0 and taso != u_taso:
                    tehty += 1
                    otsikko = self.tee_otsikko(otsikko, taso);
#                    print u"otsikko: " + otsikko
                    oteksti.append(otsikko)
                else:
                    oteksti.append(m.group(0))

                stack.append((u_taso, otsikko))
                a = a + m.end()

        oteksti.append(iteksti[a:])
        if tehty > 0:
            self.teot.append(u"otsikon taso korjattu")

        print u"DATA NYT:" + u"".join(oteksti)[1:] + "\n\n"
        return u"".join(oteksti)[1:]


    def parsi_rakenne(self, data):
        iteksti = u"\n" + data
        odata = []
        re_m = re.compile(u"\n(==+ *)(.*?)( *==+ *)")
        a = 0
        m = True
        while m:
            m = re.search(re_m, iteksti[a:])

            if m:
                odata.append(m.group(2))
                a = a + m.end()

        return odata


if __name__ == "__main__":
    import sys
    fn = sys.argv[1]
    with codecs.open(fn, u"r", encoding="utf-8") as f:
        lines = f.read()

    kp = KorjausParseri(lines)
    print "TULOS:"
    print kp.teksti()

    print "TUOMIO: {}".format(kp.teot)

